import i18next from 'i18next';
import { create } from 'zustand';
import { useShallow } from 'zustand/shallow';
import { initReactI18next, useTranslation } from 'react-i18next';
import app_config from '@/configs/app.config.json';
import langs from '@/configs/langs/index.ts';
import ConfigManager from '@/configs/ConfigManager.ts';
import ToastManager from '@/components/Toast/ToastManager.ts';
import ModalManager from '@/components/base/Modal/ModalManager';
import PageService from '@/utils/PageService';
import Http from '@/utils/Http.ts';

// 服务注册中心（简化示例）

interface TPageService extends PageService{

}

class ServiceRegistry {
    private services = new Map<string, TPageService>();

    register(service: TPageService) {
        const name = service.name;
        if (this.services.has(name)) {
            console.warn(`Service ${name} is already registered.`);
        } else {
            this.services.set(name, service);
        }
    }
    
    exist(name: string) {
        return this.services.has(name);
    }

    get(name: string) {
        return this.services.get(name);
    }
}

const registry = new ServiceRegistry();

class Base {
    public i18n: any = null;
    public configmrg: ConfigManager;
    public toastmgr: ToastManager;
    public modalmgr: ModalManager;
    public global: {
        [key: string]: any;
    } = {
            Http: Http
        };
    public translate: any = useTranslation;
    constructor(config: { [key: string]: any }) {
        this.i18n = i18next.use(initReactI18next);
        this.i18n.init({
            resources: {
                en: { translation: langs.enUS },
                cn: { translation: langs.zhCN }
            },
            lng: 'cn',
            fallbackLng: 'en',
            interpolation: {
                escapeValue: false
            }
        });
        this.configmrg = new ConfigManager(config);
        this.toastmgr = new ToastManager();
        this.modalmgr = new ModalManager();
    }

    public path(target: { [key: string]: any }, path: string, value?: any) {
        let _result = target || {};
        if (path) {
            var _tokens = path.split('.'),
                _token,
                _len = _tokens.length,
                i = 0;

            if (arguments.length < 3) {
                for (; _result && i < _len; i++) {
                    _token = _tokens[i];
                    if (_result.__get__) {
                        if (_result.__get__(_token)) {
                            _result = _result.__get__(_token);
                        } else if (_result[_token]) {
                            _result = _result[_token];
                        }
                    } else {
                        _result = _result[_token];
                    }
                }
            } else {
                _len -= 1;
                for (; _result && i < _len; i++) {
                    _token = _tokens[i];
                    if (_result.__get__) {
                        _result = _result.__get__(_token);
                    } else {
                        _result = _result[_token] = _result[_token] || {};
                    }
                }

                _token = _tokens[i];
                if (_result) {
                    if (_result.__set__) {
                        _result.__set__(_token, value);
                    } else {
                        _result[_token] = value;
                    }

                    _result = value;
                }
            }
        }

        return _result;
    }

    public registerService(name: string, url?: string) {
        url = url || '/api';
        if(registry.exist(name)) {
            return <T extends new (...args: any[]) => PageService>(constructor: T) => constructor;
        }
        return function <T extends new (...args: any[]) => PageService>(constructor: T) {
            // 实例化服务并注册
            constructor.prototype.name = name;
            constructor.prototype.baseUrl = url;
            const instance = new constructor(name, url);
            instance.name = name;
            instance.baseUrl = url;
            if (!(instance instanceof PageService)) {
                throw new Error(`Service ${name} is not instance of PageService.`);
            }

            registry.register(instance);
            // 返回构造函数（可选，通常原样返回即可）
            return constructor;
        };
    }

    public defineStore(callback: (set: any) => any) {
        const _useStore_ = create(callback), _empty_ = {};
        return (...keys: string[]): { [key: string]: any } => {
            if (keys.length === 0) return _empty_;
            return _useStore_(
                useShallow((state: any) => {
                    if (state) {
                        return keys.reduce((acc, key) => ({ ...acc, [key]: state[key] }), {});
                    } else {
                        return _empty_;
                    }
                })
            );
        };
    }

    public getService<T extends typeof PageService>(name: string | T): any {
        if (typeof name === 'function' && Object.prototype.hasOwnProperty.call(name, 'prototype') && name.prototype instanceof PageService) {
            name = name.prototype.name;
        }
        let _service = null;
        if (name && typeof name === 'string') {
            _service = registry.get(name);
        }

        if(!_service) {
            throw new Error("Cann't find the service!");
        }

        return _service;
    }

    public useVars(...args: any[]) {
        for (const arg of args) {
            if (arg) {
                arg.toString();
            }
        }
    }

    /**
     * Show a confirmation dialog
     * @param message The message to display
     * @returns A promise that resolves to true if confirmed, false otherwise
     */
    public showConfirm(message: string): Promise<boolean> {
        return new Promise((resolve) => {
            resolve(window.confirm(message));
        });
    }

    public downloadBlobAsFile(obj: Blob | MediaSource, filename: string) {
        try {
            // Create download link
            const url = window.URL.createObjectURL(obj);
            const a = document.createElement('a');
            a.href = url;
            a.download = filename;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            window.URL.revokeObjectURL(url);
        } catch (error) {
            console.error('Error downloading backup:', error);
            base.toastmgr.show('MODULE_CONFIG.MESSAGES.DOWNLOAD_ERROR', 'danger');
        }
    }
}

declare global {
    interface Window {
        base: Base;
        bootstrap: {
            Toast: new (element: Element, options?: any) => { show: () => void; hide: () => void };
        };
    }
    interface Base {
        i18n: any;
        global: {
            [key: string]: any;
        };
        configmrg: ConfigManager;
        toastmgr: ToastManager;
        modalmgr: ModalManager;
        translate: Function;
        path: (target: { [key: string]: any }, path: string, value?: any) => any;
        registerService(name: string, url?: string): <T extends new (...args: any[]) => PageService>(constructor: T) => T;
        getService<T extends typeof PageService>(name: string | T): any;
        defineStore: (callback: (set: any) => any) => (...args: any[]) => { [key: string]: any };
        useVars: (...args: any[]) => void;
        showConfirm: (message: string) => Promise<boolean>;
        downloadBlobAsFile: (obj: Blob | MediaSource, filename: string) => void;
    }
    const base: Base
}

// Initialize the global object
if (!window.base) {
    window.base = new Base(app_config);
}

export default window.base;